home *** CD-ROM | disk | FTP | other *** search
- /*
- * fsrmtDomain.c --
- *
- * This has the stubs for remote naming operations in a Sprite domain.
- * These routines are presented in pairs, the client stub followed
- * by the server stub. The general style is for the server stub
- * to call the LocalDomain equivalent of the SpriteDomain client stub.
- * i.e. FsrmtOpen invokes via RPC Fsrmt_RpcOpen which calls
- * FslclOpen. Occasionally a client or server stub will do some
- * extra processing, or use lower level primatives for efficiency.
- *
- * Copyright (C) 1987 Regents of the University of California
- * All rights reserved.
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/fsrmt/fsrmtDomain.c,v 9.15 92/12/13 18:16:58 mgbaker Exp $ SPRITE (Berkeley)";
- #endif not lint
-
- #include <sprite.h>
- #include <fs.h>
- #include <fsconsist.h>
- #include <fsio.h>
- #include <fsutil.h>
- #include <fsNameOps.h>
- #include <fsrmtNameOpsInt.h>
- #include <fsprefix.h>
- #include <fsrmtInt.h>
- #include <fslcl.h>
- #include <fsStat.h>
- #include <recov.h>
- #include <proc.h>
- #include <rpc.h>
- #include <vm.h>
- #include <dbg.h>
-
- #include <string.h>
- #include <rpcServer.h>
-
- /*
- * Used to contain fileID and stream data results from open calls.
- */
- typedef struct FsPrefixReplyParam {
- FsrmtUnionData openData;
- Fs_FileID fileID;
- } FsPrefixReplyParam;
-
- static ReturnStatus TwoNameOperation _ARGS_((int command,
- Fs_HandleHeader *prefixHandle1, char *relativeName1,
- Fs_HandleHeader *prefixHandle2, char *relativeName2,
- Fs_LookupArgs *lookupArgsPtr, Fs_RedirectInfo **newNameInfoPtrPtr,
- Boolean *name1ErrorPtr));
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtImport --
- *
- * Get a handle for a prefix. This conducts an RPC_FS_PREFIX
- * to see if there is a server for the prefix. If there is one this
- * routine installs a handle for it. The pointer to the handle
- * is returned.
- *
- * Results:
- * FAILURE or RPC_TIMEOUT if we couldn't find a server for the prefix.
- * SUCCESS if we did find a server. In this case the results are
- * a pointer to a handle for the prefix.
- *
- * Side effects:
- * State is left on the server machine about the open prefix. The
- * responding file server is registered with the recovery module
- * so we find out when it goes away and when it reboots.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- FsrmtImport(prefix, serverID, idPtr, domainTypePtr, hdrPtrPtr)
- char *prefix; /* Prefix for which to find a server. */
- int serverID; /* Suggested server ID. This is the
- * broadcast address for nearby domains,
- * or a specific hostID, or a remote
- * network for remote broadcasting */
- Fs_UserIDs *idPtr; /* IGNORED */
- int *domainTypePtr; /* Return - FS_REMOTE_SPRITE_DOMAIN or
- * FS_REMOTE_PSEUDO_DOMAIN */
- Fs_HandleHeader **hdrPtrPtr; /* Return - handle for prefix table */
- {
- ReturnStatus status;
- Rpc_Storage storage;
- Fs_FileID *fileIDPtr; /* Returned from server */
- ClientData streamData; /* Returned from server */
- int flags = FS_PREFIX;
- FsPrefixReplyParam prefixReplyParam;
-
- *hdrPtrPtr = (Fs_HandleHeader *)NIL;
- *domainTypePtr = -1;
-
- storage.requestParamPtr = (Address) NIL;
- storage.requestParamSize = 0;
- storage.requestDataPtr = (Address)prefix;
- storage.requestDataSize = strlen(prefix)+1;
-
- storage.replyParamPtr = (Address)&prefixReplyParam;
- storage.replyParamSize = sizeof(FsPrefixReplyParam);
- storage.replyDataPtr = (Address)NIL;
- storage.replyDataSize = 0;
- fileIDPtr = &(prefixReplyParam.fileID);
-
- status = Rpc_Call(serverID, RPC_FS_PREFIX, &storage);
- /*
- * It is necessary to allocate and copy over the stream data, since
- * the ioOpen proc frees this space.
- */
- streamData = (ClientData)malloc(sizeof(FsrmtUnionData));
- *((FsrmtUnionData *) streamData) = prefixReplyParam.openData;
-
- if (status == SUCCESS) {
- /*
- * Use the client-open routine to set up an I/O handle for the prefix.
- */
- status = (*fsio_StreamOpTable[fileIDPtr->type].ioOpen)(fileIDPtr, &flags,
- rpc_SpriteID, (ClientData)streamData, prefix, hdrPtrPtr);
- if (status == SUCCESS) {
- /*
- * Register the server with the recovery module so we find out
- * when it goes away and when it reboots.
- */
- Recov_RebootRegister((*hdrPtrPtr)->fileID.serverID, Fsutil_Reopen,
- (ClientData)NIL);
- *domainTypePtr = FS_REMOTE_SPRITE_DOMAIN;
- }
- }
-
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcPrefix --
- *
- * Server stub for RPC_FS_PREFIX. This looks in the prefix
- * table for the given prefix. If found, the handle is opened
- * for use by the client, and the resulting streamData is returned.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then an error is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * The nameOpen routine is called on the prefix handle. This ups
- * reference counts.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcPrefix(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* IGNORED */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- char *lookupName;
- Fsprefix *prefixPtr;
- Fs_HandleHeader *hdrPtr;
- Fs_FileID rootID;
- int domainType;
- int serverID;
- ReturnStatus status;
- FsPrefixReplyParam *prefixReplyPtr;
-
- status = Fsprefix_Lookup((char *) storagePtr->requestDataPtr,
- FSPREFIX_EXPORTED | FSPREFIX_EXACT, clientID, &hdrPtr,
- &rootID, &lookupName, &serverID, &domainType, &prefixPtr);
- if (status == SUCCESS) {
- register Rpc_ReplyMem *replyMemPtr;
- ClientData streamData;
- int dataSize;
-
- prefixReplyPtr = mnew(FsPrefixReplyParam);
- status = (*fs_DomainLookup[domainType][FS_DOMAIN_EXPORT])(hdrPtr,
- clientID, &prefixReplyPtr->fileID, &dataSize, &streamData);
- if (status == SUCCESS) {
- if (dataSize > 0) {
- bcopy((Address)streamData, (Address)&prefixReplyPtr->openData,
- dataSize);
- free((Address)streamData);
- }
- storagePtr->replyParamPtr = (Address) (prefixReplyPtr);
- storagePtr->replyParamSize = sizeof(FsPrefixReplyParam);
- storagePtr->replyDataPtr = (Address)NIL;
- storagePtr->replyDataSize = 0;
-
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, SUCCESS, storagePtr, Rpc_FreeMem,
- (ClientData)replyMemPtr);
- return(SUCCESS);
- } else {
- free((Address)prefixReplyPtr);
- printf( "Fsrmt_RpcPrefix, export \"%s\" failed %x\n",
- storagePtr->requestDataPtr, status);
- Fsprefix_HandleClose(prefixPtr, FSPREFIX_ANY);
- }
- }
- if (RPC_IS_BROADCAST(srvToken)) {
- return(RPC_NO_REPLY);
- } else {
- return(RPC_FS_NO_PREFIX);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtOpen --
- *
- * Open a remote file. This sets up and conducts an RPC_FS_OPEN
- * remote procedure call to open the remote file. This is called
- * from Fsprefix_LookupOperation based on the prefix table. FsrmtOpen
- * makes an RPC to FslclOpen on the remote machine, and returns
- * the streamData for use by the client-open routine.
- *
- * RPC: The input parameters are the Fs_OpenArgs defined in fsNameOps.h.
- * The input data is a relative name. The return parameter is a file
- * type used by our caller to branch to the client-open routine. The
- * return data area has two possible return values. In the normal
- * case it is a lump of data used by the client-open routine to set
- * up the I/O handle. If the name lookup re-directs to a different
- * server then the returned data is the new pathname.
- *
- * Results:
- * SUCCESS, FS_REDIRECT, or some error code from the lookup on the server.
- * If FS_REDIRECT, then *newNameInfoPtr has prefix information.
- *
- * Side effects:
- * Allocates memory for the returned streamData or re-directed path.
- * An openCount is left up during the open as part of the open/re-open
- * synchronization.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- FsrmtOpen(prefixHandle, relativeName, argsPtr, resultsPtr,
- newNameInfoPtrPtr)
- Fs_HandleHeader *prefixHandle; /* Token from the prefix table */
- char *relativeName; /* The name of the file to open. */
- Address argsPtr; /* Ref. to Fs_OpenArgs */
- Address resultsPtr; /* Ref. to Fs_OpenResults */
- Fs_RedirectInfo **newNameInfoPtrPtr; /* We return this if
- * the server leaves
- * its domain during lookup. */
- {
- ReturnStatus status;
- Fs_OpenResults *openResultsPtr = (Fs_OpenResults *)resultsPtr;
- Rpc_Storage storage; /* Specifies RPC parameters/results */
- char replyName[FS_MAX_PATH_NAME_LENGTH]; /* This
- * may get filled with a
- * redirected pathname */
- FsrmtOpenResultsParam openResultsParam;
- /*
- * Synchronize with the re-open phase of recovery.
- * We don't want opens to race with the recovery actions.
- */
- status = Fsprefix_OpenCheck(prefixHandle);
- if (status != SUCCESS) {
- return(status);
- }
-
- /*
- * Set up for the RPC.
- */
- storage.requestParamPtr = (Address) argsPtr;
- storage.requestParamSize = sizeof(Fs_OpenArgs);
- storage.requestDataPtr = (Address) relativeName;
- storage.requestDataSize = strlen(relativeName) + 1;
- storage.replyParamPtr = (Address) &openResultsParam;
- storage.replyParamSize = sizeof(FsrmtOpenResultsParam);
- storage.replyDataPtr = (Address) replyName;
- storage.replyDataSize = FS_MAX_PATH_NAME_LENGTH;
-
- status = Rpc_Call(prefixHandle->fileID.serverID, RPC_FS_OPEN, &storage);
- if (status == SUCCESS) {
- /*
- * Allocate space for the stream data returned by the server.
- * We then copy the streamData from our stack buffer.
- */
- /* This assumes openResults.dataSize was filled in correctly. */
- *openResultsPtr = openResultsParam.openResults;
- if (openResultsPtr->dataSize == 0) {
- openResultsPtr->streamData = (ClientData)NIL;
- } else {
- openResultsPtr->streamData =
- (ClientData)malloc(openResultsPtr->dataSize);
- bcopy((Address) &(openResultsParam.openData), (Address) openResultsPtr->streamData, openResultsPtr->dataSize);
- }
- } else if (status == FS_LOOKUP_REDIRECT) {
- /*
- * Allocate space for the re-directed pathname and
- * copy over the structure that we have on our stack. A large
- * buffer is allocated because it is used as a work area in
- * FsprefixLookupRedirect to create a new absolute pathname.
- */
- *newNameInfoPtrPtr = mnew(Fs_RedirectInfo);
- (*newNameInfoPtrPtr)->prefixLength = openResultsParam.prefixLength;
- (void)strcpy((*newNameInfoPtrPtr)->fileName, replyName);
- }
- Fsprefix_OpenDone(prefixHandle);
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcOpen --
- *
- * Service stub for the RPC_FS_OPEN call. This unpackages parameters
- * and branches to the local open routine.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then an error is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * None here, see FslclOpen.
- *
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcOpen(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* IGNORED */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- ReturnStatus status;
- register Fs_OpenArgs *openArgsPtr; /* RPC parameters */
- register Fs_OpenResults *openResultsPtr; /* RPC results */
- Fs_HandleHeader *prefixHandlePtr; /* Handle for domain */
- Fs_RedirectInfo *newNameInfoPtr; /* prefix info for
- * redirected lookups */
- FsrmtOpenResultsParam *openResultsParamPtr; /* open results, etc. */
- int domainType; /* Local or Pseudo */
-
-
- if (Recov_GetClientState(clientID) & CLT_RECOV_IN_PROGRESS) {
- Net_HostPrint(clientID, "Dropping regular open during recovery\n");
- return(RPC_SERVICE_DISABLED);
- }
- openArgsPtr = (Fs_OpenArgs *) storagePtr->requestParamPtr;
- /*
- * Get a handle on the prefix. We need to have it unlocked in case
- * we do I/O on the directory.
- */
- prefixHandlePtr =
- (*fsio_StreamOpTable[openArgsPtr->prefixID.type].clientVerify)
- (&openArgsPtr->prefixID, clientID, &domainType);
- if (prefixHandlePtr == (Fs_HandleHeader *)NIL) {
- return(FS_STALE_HANDLE);
- }
- Fsutil_HandleUnlock(prefixHandlePtr);
-
- newNameInfoPtr = (Fs_RedirectInfo *) NIL;
- openResultsParamPtr = mnew(FsrmtOpenResultsParam);
- openResultsPtr = &(openResultsParamPtr->openResults);
- fs_Stats.srvName.numReadOpens++;
- status = (*fs_DomainLookup[domainType][FS_DOMAIN_OPEN])(prefixHandlePtr,
- (char *)storagePtr->requestDataPtr, (Address)openArgsPtr,
- (Address)openResultsPtr, &newNameInfoPtr);
- Fsutil_HandleRelease(prefixHandlePtr, FALSE);
- if (status == SUCCESS) {
- /*
- * The open worked. We return the whole Fs_OpenResults structure
- * in the RPC parameter area, but it contains a pointer to
- * stream data and a dataSize. That stream data is returned also
- * as a separate field in the RPC parameter area, so it must be copied.
- */
- storagePtr->replyParamPtr = (Address)openResultsParamPtr;
- storagePtr->replyParamSize = sizeof(FsrmtOpenResultsParam);
- /* copy openData */
- if (openResultsPtr->dataSize != 0 &&
- ((Address)openResultsPtr->streamData) != (Address)NIL) {
- bcopy((Address)openResultsPtr->streamData, (Address)&openResultsParamPtr->openData, openResultsPtr->dataSize);
- free((Address)openResultsPtr->streamData);
- storagePtr->replyDataPtr = (Address)NIL;
- storagePtr->replyDataSize = 0;
- }
- } else if (status == FS_LOOKUP_REDIRECT) {
- /*
- * The file is not found on this server.
- */
- storagePtr->replyParamPtr = (Address)openResultsParamPtr;
- storagePtr->replyParamSize = sizeof(FsrmtOpenResultsParam);
- openResultsParamPtr->prefixLength = newNameInfoPtr->prefixLength;
- storagePtr->replyDataSize = strlen(newNameInfoPtr->fileName) + 1;
- storagePtr->replyDataPtr = (Address)malloc(storagePtr->replyDataSize);
- (void)strcpy(storagePtr->replyDataPtr, newNameInfoPtr->fileName);
- free((Address)newNameInfoPtr);
- }
- if (status == SUCCESS || status == FS_LOOKUP_REDIRECT) {
- Rpc_ReplyMem *replyMemPtr;
-
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, status, storagePtr, Rpc_FreeMem,
- (ClientData)replyMemPtr);
- return(SUCCESS);
- } else {
- free((Address)openResultsParamPtr);
- return(status);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtReopen --
- *
- * Open a handle at its server. This sets up and conducts an RPC_FS_REOPEN
- * remote procedure call to reopen the remote file handle.
- *
- * Results:
- * The return from the RPC.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- FsrmtReopen(hdrPtr, inSize, inData, outSizePtr, outData)
- Fs_HandleHeader *hdrPtr; /* Handle to reopen */
- int inSize; /* Size of input data */
- Address inData; /* Input data to server's reopen proc */
- int *outSizePtr; /* In/Out return data size */
- Address outData; /* Return parameter block */
- {
- register ReturnStatus status;
- Rpc_Storage storage; /* Specifies RPC parameters/results */
-
- storage.requestParamPtr = inData;
- storage.requestParamSize = inSize;
- storage.requestDataPtr = (Address) NIL;
- storage.requestDataSize = 0;
- storage.replyParamPtr = outData;
- storage.replyParamSize = *outSizePtr;
- storage.replyDataPtr = (Address) NIL;
- storage.replyDataSize = 0;
-
- status = Rpc_Call(hdrPtr->fileID.serverID, RPC_FS_REOPEN, &storage);
- *outSizePtr = storage.replyParamSize;
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcReopen --
- *
- * This is the service stub for RPC_FS_REOPEN. This switches
- * out to a stream type reopen procedure. To do this it must
- * assume that the first part of the parameter block contains
- * a fileID, the thing to be re-opened.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then an error is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * None.
- *
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcReopen(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* IGNORED */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- register Fs_FileID *fileIDPtr;
- register ReturnStatus status;
-
- extern int fsutil_NumRecovering; /* XXX put in fsutil.h */
-
- if (storagePtr->requestParamSize <= 0) {
- /*
- * Check to make sure our parameter size is big enough to be
- * a proper reopen request. (As of 1/91, we've been suffering
- * from a 0 paramSize bug in reopen requests.)
- */
- Net_HostPrint(clientID, "Zero-length parameters to reopen request!\n");
- return FAILURE;
- }
- if ((Recov_GetClientState(clientID) & CLT_RECOV_IN_PROGRESS) == 0) {
- Recov_SetClientState(clientID, CLT_RECOV_IN_PROGRESS);
- fsutil_NumRecovering++;
- if (fsutil_NumRecovering == 1) {
- /*
- * The print statements are tweaked so that the first client
- * to recover triggers this message, and the last
- * client to end recovery triggers another message.
- * See fsRecovery.c for the complementary printf.
- */
- Net_HostPrint(clientID, "initiating recovery\n");
- }
- }
-
- fileIDPtr = (Fs_FileID *)storagePtr->requestParamPtr;
- if (fileIDPtr->serverID != rpc_SpriteID) {
- /*
- * Filesystem version mis-match.
- */
- return(GEN_INVALID_ARG);
- }
- fileIDPtr->type = Fsio_MapRmtToLclType(fileIDPtr->type);
- if (fileIDPtr->type < 0) {
- return(GEN_INVALID_ARG);
- }
- status = (*fsio_StreamOpTable[fileIDPtr->type].reopen)((Fs_HandleHeader *)NIL,
- clientID, (ClientData) storagePtr->requestParamPtr,
- &storagePtr->replyParamSize,
- (ClientData *)&storagePtr->replyParamPtr);
-
- Recov_AddHandleCountToClientState(fileIDPtr->type, clientID, status);
-
- if (status == SUCCESS) {
- Rpc_ReplyMem *replyMemPtr;
-
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, SUCCESS, storagePtr, Rpc_FreeMem,
- (ClientData)replyMemPtr);
- }
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtBulkReopen --
- *
- * Open a set of handles at the server. This sets up and conducts an
- * RPC_FS_BULK_REOPEN
- * remote procedure call to reopen the remote file handles.
- *
- * Results:
- * The return from the RPC.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- FsrmtBulkReopen(serverID, inSize, inData, outSizePtr, outData)
- int serverID; /* Server to do reopens. */
- int inSize; /* Size of input data */
- Address inData; /* Input data to server's reopen proc */
- int *outSizePtr; /* In/Out return data size */
- Address outData; /* Return parameter block */
- {
- register ReturnStatus status;
- Rpc_Storage storage; /* Specifies RPC parameters/results */
- Fmt_Format sendFormat = mach_Format;
- Fmt_Format returnFormat;
- int fmtStatus;
-
- storage.requestParamPtr = (Address) &sendFormat;
- storage.requestParamSize = sizeof (mach_Format);
- storage.requestDataPtr = inData;
- storage.requestDataSize = inSize;
- storage.replyParamPtr = (Address) &returnFormat;
- storage.replyParamSize = sizeof (Fmt_Format);;
- storage.replyDataPtr = (Address) malloc(*outSizePtr);
- storage.replyDataSize = *outSizePtr;
-
- status = Rpc_Call(serverID, RPC_FS_BULK_REOPEN, &storage);
- if (storage.replyDataSize > *outSizePtr) {
- panic("FsrmtBulkReopen: size of return data is too large.");
- }
- if (status == SUCCESS) {
- if (mach_Format != returnFormat) {
- int outSize;
-
- inSize = storage.replyDataSize;
- if (Fmt_Size("w*", returnFormat, &inSize, mach_Format,
- &outSize) != 0 || outSize > storage.replyDataSize) {
- /*
- * Different alignment on two machines. This isn't
- * set up to deal with this, since I'm assuming that
- * all the stuff here is int's and won't have different
- * alignnment properties.
- */
- printf("FsrmtBulkReopen: bad alignment on two machines.");
- free((char *) storage.replyDataPtr);
- return GEN_INVALID_ARG;
- }
- inSize = storage.replyDataSize;
- fmtStatus = Fmt_Convert("w*", returnFormat, &inSize,
- storage.replyDataPtr, mach_Format, &outSize, outData);
- if (fmtStatus != 0) {
- printf("Format of bulk reopen failed <0x%x>\n", fmtStatus);
- free((char *) storage.replyDataPtr);
- return GEN_INVALID_ARG;
- }
- *outSizePtr = outSize;
- } else {
- *outSizePtr = storage.replyDataSize;
- bcopy(storage.replyDataPtr, outData, *outSizePtr);
- }
- }
-
- free((char *) storage.replyDataPtr);
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcBulkReopen --
- *
- * This is the service stub for RPC_FS_BULK_REOPEN. This switches
- * out to stream type reopen procedures.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then an error is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * None.
- *
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcBulkReopen(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* IGNORED */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- ReturnStatus status;
- Fsutil_BulkHandle *bulkHandleSpace;
- int numBulkHandles;
- Fsutil_BulkReturn *bulkReturnSpace;
- int i;
- Address newStatePtr;
- int newSize;
- Fmt_Format inFormat;
- Rpc_ReplyMem *replyMemPtr;
- int fmtStatus;
-
- extern int fsutil_NumRecovering; /* XXX put in fsutil.h */
-
- if (storagePtr->requestParamSize != sizeof (Fmt_Format)) {
- /*
- * Check to make sure our parameter size is correct for
- * a proper reopen request.
- */
- Net_HostPrint(clientID, "Bad length params to bulk reopen request!\n");
- return FAILURE;
- }
- if (storagePtr->requestDataSize <= 0) {
- Net_HostPrint(clientID, "Zero-length data to bulk reopen request!\n");
- return FAILURE;
- }
- if ((Recov_GetClientState(clientID) & CLT_RECOV_IN_PROGRESS) == 0) {
- Recov_SetClientState(clientID, CLT_RECOV_IN_PROGRESS);
- fsutil_NumRecovering++;
- if (fsutil_NumRecovering == 1) {
- /*
- * The print statements are tweaked so that the first client
- * to recover triggers this message, and the last
- * client to end recovery triggers another message.
- * See fsRecovery.c for the complementary printf.
- */
- Net_HostPrint(clientID, "initiating recovery\n");
- }
- }
- inFormat = *((Fmt_Format *) (storagePtr->requestParamPtr));
- if (inFormat != mach_Format) {
- int inSize;
- int outSize;
-
- inSize = storagePtr->requestDataSize;
- if (Fmt_Size("w*", inFormat, &inSize, mach_Format, &outSize) != 0 ||
- outSize > storagePtr->requestDataSize) {
- /*
- * Different alignment on two machines. This isn't
- * set up to deal with this, since I'm assuming that
- * all the stuff here is int's and won't have different
- * alignnment properties.
- */
- printf("Fsrmt_RpcBulkReopen: bad alignment on two machines.");
- return GEN_INVALID_ARG;
- }
-
- inSize = storagePtr->requestDataSize;
- bulkHandleSpace = (Fsutil_BulkHandle *) malloc(outSize);
- fmtStatus = Fmt_Convert("w*", inFormat, &inSize,
- (Address) storagePtr->requestDataPtr, mach_Format, &outSize,
- (Address) bulkHandleSpace);
- if (fmtStatus != 0) {
- printf("Format of bulk reopen failed <0x%x>\n", fmtStatus);
- free((char *) bulkHandleSpace);
- return GEN_INVALID_ARG;
- }
- storagePtr->requestDataSize = outSize;
- } else {
- bulkHandleSpace = (Fsutil_BulkHandle *) (storagePtr->requestDataPtr);
- }
- numBulkHandles = storagePtr->requestDataSize / sizeof (Fsutil_BulkHandle);
- storagePtr->replyDataPtr =
- (Address) malloc(numBulkHandles * sizeof (Fsutil_BulkReturn));
- bulkReturnSpace = (Fsutil_BulkReturn *) (storagePtr->replyDataPtr);
- storagePtr->replyDataSize = numBulkHandles * sizeof (Fsutil_BulkReturn);
-
- for (i = 0; i < numBulkHandles; i++) {
- newStatePtr = (Address) NIL;
- newSize = 0;
- if (bulkHandleSpace[i].serverID != rpc_SpriteID) {
- /*
- * Filesystem version mis-match.
- */
- bulkReturnSpace[i].status = GEN_INVALID_ARG;
- continue;
- }
- bulkHandleSpace[i].type = Fsio_MapRmtToLclType(bulkHandleSpace[i].type);
- if (bulkHandleSpace[i].type < 0) {
- bulkReturnSpace[i].status = GEN_INVALID_ARG;
- continue;
- }
- status = (*fsio_StreamOpTable[bulkHandleSpace[i].type].reopen)
- ((Fs_HandleHeader *)NIL,
- clientID, (ClientData) (bulkHandleSpace[i].reopenParams),
- &newSize, (ClientData *) &newStatePtr);
- if (newSize != 0) {
- bcopy((Address) newStatePtr, (Address) bulkReturnSpace[i].state,
- newSize);
- free((Address) newStatePtr);
- }
-
- Recov_AddHandleCountToClientState(bulkHandleSpace[i].type, clientID,
- status);
- bulkReturnSpace[i].status = status;
- }
-
- if (inFormat != mach_Format) {
- free((char *) bulkHandleSpace);
- }
- storagePtr->replyParamPtr = (Address) malloc(sizeof (Fmt_Format));
- *((Fmt_Format *) storagePtr->replyParamPtr) = mach_Format;
- storagePtr->replyParamSize = sizeof (Fmt_Format);
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, SUCCESS, storagePtr, Rpc_FreeMem,
- (ClientData) replyMemPtr);
-
- return SUCCESS;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_ServerReopen --
- *
- * Tell client to begin recovery with server.
- *
- * Results:
- * The return from the RPC.
- *
- * Side effects:
- * May determine that client is running an old kernel.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- Fsrmt_ServerReopen(clientID)
- int clientID; /* Client to start reopens. */
- {
- ReturnStatus status;
- Rpc_Storage storage; /* Specifies RPC parameters/results */
-
- storage.requestParamPtr = (Address) NIL;
- storage.requestParamSize = 0;
- storage.requestDataPtr = (Address) NIL;
- storage.requestDataSize = 0;
- storage.replyParamPtr = (Address) NIL;
- storage.replyParamSize = 0;
- storage.replyDataPtr = (Address) NIL;
- storage.replyDataSize = 0;
-
- status = Rpc_Call(clientID, RPC_FS_SERVER_REOPEN, &storage);
-
- return status;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcServerReopen --
- *
- * This is the service stub for RPC_FS_SERVER_REOPEN. This
- * is executed by clients to begin their recovery with the server.
- *
- * Results:
- * Status for RPC (success always, I think?).
- *
- * Side effects:
- * Start recovery stuff.
- *
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcServerReopen(srvToken, serverID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int serverID; /* Sprite ID of server calling us */
- int command; /* IGNORED */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- /*
- * Start recovery things in motion on client.
- */
- if (recov_ClientIgnoreServerDriven) {
- return RPC_INVALID_RPC;
- }
- Recov_StartServerDrivenRecovery(serverID);
- Rpc_Reply(srvToken, SUCCESS, storagePtr, (int (*)())NIL, (ClientData)NIL);
-
- return SUCCESS;
- }
-
- /*
- * Union of things passed as close data. Right now, it only seems to
- * be cached attributes.
- */
- typedef union FsCloseData {
- Fscache_Attributes attrs;
- } FsCloseData;
-
-
- /*
- * Request params for the close RPC. The data for the close is put in the
- * closeData field so that it too can be byte-swapped. The field is for stream
- * specific data that gets pushed back to the server when the client closes.
- * Currently, it seems only to be Fscache_Attributes.
- *
- */
-
-
- typedef struct FsRemoteCloseParams {
- Fs_FileID fileID; /* File to close */
- Fs_FileID streamID; /* Stream to close */
- Proc_PID procID; /* Process doing the close */
- int flags; /* Flags from the stream */
- FsCloseData closeData; /* Seems to be only Fscache_Attributes... */
- int closeDataSize; /* actual size of info in closeData field. */
- } FsRemoteCloseParams;
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_Close --
- *
- * Tell the server that we have closed one reference to its file. This
- * is used by the remote file and remote device close routines. This
- * routine uses RPC_FS_CLOSE to invoke the correct stream-type close
- * routine on the I/O server.
- *
- * Results:
- * SUCCESS.
- *
- * Side effects:
- * This marks the handle as needing recovery if the RPC fails due
- * to communication problems.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_Close(streamPtr, clientID, procID, flags, dataSize, closeData)
- Fs_Stream *streamPtr; /* Stream to close. This is needed
- * (instead of I/O handle) so the
- * server can close its shadow stream */
- int clientID; /* IGNORED, implicitly passed by RPC */
- Proc_PID procID; /* Process ID of closer */
- int flags; /* Flags from the stream being closed */
- int dataSize; /* Size of *closeData, or Zero */
- ClientData closeData; /* Copy of cached I/O attributes.
- * Sometimes NIL! */
- {
- Fsrmt_IOHandle *rmtHandlePtr; /* Handle to close */
- Rpc_Storage storage;
- ReturnStatus status;
-
- FsRemoteCloseParams params;
- rmtHandlePtr = (Fsrmt_IOHandle *)streamPtr->ioHandlePtr;
- params.fileID = rmtHandlePtr->hdr.fileID;
- params.streamID = streamPtr->hdr.fileID;
- params.procID = procID;
- params.flags = flags;
- if (closeData != (ClientData) NIL) {
- params.closeData = *((FsCloseData *)closeData);
- params.closeDataSize = dataSize;
- } else {
- params.closeDataSize = 0;
- }
- storage.requestParamPtr = (Address)¶ms;
- storage.requestParamSize = sizeof(params);
- storage.requestDataPtr = (Address)NIL;
- storage.requestDataSize = 0;
- storage.replyParamPtr = (Address)NIL;
- storage.replyParamSize = 0;
- storage.replyDataPtr = (Address)NIL;
- storage.replyDataSize = 0;
-
- status = Rpc_Call(rmtHandlePtr->hdr.fileID.serverID, RPC_FS_CLOSE,&storage);
-
- if (status == RPC_TIMEOUT || status == FS_STALE_HANDLE ||
- status == RPC_SERVICE_DISABLED) {
- /*
- * Mark the handle as needing recovery if we can't tell the server
- * about this close.
- */
- Fsutil_WantRecovery((Fs_HandleHeader *)rmtHandlePtr);
- }
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcClose --
- *
- * Server stub for RPC_FS_CLOSE. This verifies the client and branches
- * to the stream-type close routine.
- *
- * Results:
- * STALE_HANDLE if the handle is out-of-date. FS_FILE_REMOVED is returned
- * if the file has been removed. SUCCESS in the normal case, or
- * an error code from the stream-type close routine.
- *
- * Side effects:
- * None here, see the stream-type close routines.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcClose(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* IGNORED */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- register FsRemoteCloseParams *paramsPtr;
- register Fs_Stream *streamPtr;
- register Fs_HandleHeader *hdrPtr;
- ReturnStatus status;
- Fs_Stream dummy;
- register ClientData clientData;
-
- if (storagePtr->requestParamSize < sizeof(FsRemoteCloseParams)) {
- printf("Fsrmt_RpcClose: rpc from host %d had undersize param (%d)\n",
- clientID, storagePtr->requestParamSize);
- status = GEN_INVALID_ARG;
- goto exit;
- }
- paramsPtr = (FsRemoteCloseParams *) storagePtr->requestParamPtr;
-
- hdrPtr = (*fsio_StreamOpTable[paramsPtr->fileID.type].clientVerify)
- (¶msPtr->fileID, clientID, (int *)NIL);
- if (hdrPtr == (Fs_HandleHeader *) NIL) {
- status = FS_STALE_HANDLE;
- goto exit;
- }
- if (paramsPtr->streamID.type == -1) {
- /*
- * This is a close of a prefix handle which doesn't have a stream.
- */
- bzero((Address)&dummy, sizeof(Fs_Stream));
- streamPtr = &dummy;
- streamPtr->ioHandlePtr = hdrPtr;
- } else {
- streamPtr = Fsio_StreamClientVerify(¶msPtr->streamID, hdrPtr,
- clientID);
- if (streamPtr == (Fs_Stream *)NIL) {
- printf("Fsrmt_RpcClose no stream <%d> to handle <%d,%d> client %d\n",
- paramsPtr->streamID.minor,
- paramsPtr->fileID.major, paramsPtr->fileID.minor,
- clientID);
- Fsutil_HandleRelease(hdrPtr, TRUE);
- status = (paramsPtr->streamID.minor < 0) ? GEN_INVALID_ARG
- : FS_STALE_HANDLE ;
- goto exit;
- }
- }
-
- /*
- * Call the file type close routine to release the I/O handle
- * and clean up. This call unlocks and decrements the reference
- * count on the handle.
- */
- if (paramsPtr->closeDataSize != 0) {
- clientData = (ClientData)¶msPtr->closeData;
- } else {
- clientData = (ClientData)NIL;
- }
- status = (*fsio_StreamOpTable[hdrPtr->fileID.type].close)
- (streamPtr, clientID, paramsPtr->procID,
- paramsPtr->flags, paramsPtr->closeDataSize, clientData);
- #ifdef lint
- status = Fsio_FileClose(streamPtr, clientID, paramsPtr->procID,
- paramsPtr->flags, paramsPtr->closeDataSize, clientData);
- status = Fsio_PipeClose(streamPtr, clientID, paramsPtr->procID,
- paramsPtr->flags, paramsPtr->closeDataSize, clientData);
- status = Fsio_DeviceClose(streamPtr, clientID, paramsPtr->procID,
- paramsPtr->flags, paramsPtr->closeDataSize, clientData);
- status = FspdevPseudoStreamClose(streamPtr, clientID, paramsPtr->procID,
- paramsPtr->flags, paramsPtr->closeDataSize, clientData);
- #endif /* lint */
- if (streamPtr != &dummy) {
- /*
- * Take the client of the stream's list and nuke the server's
- * shadow stream if there are no client's left.
- */
- if (Fsio_StreamClientClose(&streamPtr->clientList, clientID)) {
- Fsio_StreamDestroy(streamPtr);
- } else {
- Fsutil_HandleRelease(streamPtr, TRUE);
- }
- }
- exit:
- /* XXX
- * For transparent recovery, maybe we should do something here to make
- * sure server and client agree on state?
- */
- /*
- * Send back the reply.
- */
- Rpc_Reply(srvToken, status, storagePtr, (int (*)())NIL, (ClientData)NIL);
-
- return(SUCCESS); /* So Rpc_Server doesn't return a reply msg */
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtRemove --
- *
- * This uses the RPC_FS_UNLINK call to invoke FslclRemove
- * on the file server.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Does the remove.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- FsrmtRemove(prefixHandle, relativeName, argsPtr, resultsPtr,
- newNameInfoPtrPtr)
- Fs_HandleHeader *prefixHandle; /* Handle from the prefix table */
- char *relativeName; /* The name of the file to remove */
- Address argsPtr; /* Ref to Fs_LookupArgs */
- Address resultsPtr; /* == NIL */
- Fs_RedirectInfo **newNameInfoPtrPtr; /* We return this if the server leaves
- its domain during the lookup. */
- {
- ReturnStatus status;
- Rpc_Storage storage;
- Fs_RedirectInfo redirectInfo;
- int prefixLength;
-
- storage.requestParamPtr = (Address) argsPtr;
- storage.requestParamSize = sizeof(Fs_LookupArgs);
- storage.requestDataPtr = (Address) relativeName;
- storage.requestDataSize = strlen(relativeName) + 1;
- storage.replyParamPtr = (Address) &prefixLength;
- storage.replyParamSize = sizeof (int);
- storage.replyDataPtr = (Address)&redirectInfo;
- storage.replyDataSize = sizeof(Fs_RedirectInfo);
-
- status = Rpc_Call(prefixHandle->fileID.serverID, RPC_FS_UNLINK, &storage);
- if (status == FS_LOOKUP_REDIRECT) {
- *newNameInfoPtrPtr = mnew(Fs_RedirectInfo);
- (*newNameInfoPtrPtr)->prefixLength = prefixLength;
- (void)strcpy((*newNameInfoPtrPtr)->fileName, redirectInfo.fileName);
- }
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtRemoveDir --
- *
- * Remove a directory. This uses the RPC_FS_RMDIR call to invoke
- * FslclRemoveDir on the file server.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Does the remove.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- FsrmtRemoveDir(prefixHandle, relativeName, argsPtr, resultsPtr,
- newNameInfoPtrPtr)
- Fs_HandleHeader *prefixHandle; /* Handle from the prefix table */
- char *relativeName; /* The name of the file to remove */
- Address argsPtr; /* Ref to Fs_LookupArgs */
- Address resultsPtr; /* == NIL */
- Fs_RedirectInfo **newNameInfoPtrPtr; /* We return this if the server leaves
- its domain during the lookup. */
- {
- ReturnStatus status;
- Rpc_Storage storage;
- Fs_RedirectInfo redirectInfo;
- int prefixLength;
-
- storage.requestParamPtr = (Address) argsPtr;
- storage.requestParamSize = sizeof(Fs_LookupArgs);
- storage.requestDataPtr = (Address) relativeName;
- storage.requestDataSize = strlen(relativeName) + 1;
- storage.replyParamPtr = (Address) &prefixLength;
- storage.replyParamSize = sizeof (int);
- storage.replyDataPtr = (Address)&redirectInfo;
- storage.replyDataSize = sizeof(Fs_RedirectInfo);
-
- status = Rpc_Call(prefixHandle->fileID.serverID, RPC_FS_RMDIR, &storage);
- if (status == FS_LOOKUP_REDIRECT) {
- *newNameInfoPtrPtr = mnew(Fs_RedirectInfo);
- (*newNameInfoPtrPtr)->prefixLength = prefixLength;
- (void)strcpy((*newNameInfoPtrPtr)->fileName, redirectInfo.fileName);
- }
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcRemove --
- *
- * The service stub for FS_RPC_UNLINK use to remove a file or directory.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then an error is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcRemove(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* RPC_FS_UNLINK, RPC_FS_RMDIR */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- ReturnStatus status;
- Fs_HandleHeader *prefixHandlePtr;
- Fs_RedirectInfo *newNameInfoPtr;
- Fs_LookupArgs *lookupArgsPtr;
- int domainType;
-
- lookupArgsPtr = (Fs_LookupArgs *)storagePtr->requestParamPtr;
- prefixHandlePtr =
- (*fsio_StreamOpTable[lookupArgsPtr->prefixID.type].clientVerify)
- (&lookupArgsPtr->prefixID, clientID, &domainType);
- if (prefixHandlePtr == (Fs_HandleHeader *) NIL) {
- return(FS_STALE_HANDLE);
- }
- Fsutil_HandleRelease(prefixHandlePtr, TRUE);
-
- newNameInfoPtr = (Fs_RedirectInfo *) NIL;
- switch (command) {
- case RPC_FS_UNLINK:
- fs_Stats.srvName.removes++;
- command = FS_DOMAIN_REMOVE;
- break;
- case RPC_FS_RMDIR:
- fs_Stats.srvName.removeDirs++;
- command = FS_DOMAIN_REMOVE_DIR;
- break;
- default:
- return(GEN_INVALID_ARG);
- }
- status = (*fs_DomainLookup[domainType][command])(prefixHandlePtr,
- (char *) storagePtr->requestDataPtr,
- (Address) lookupArgsPtr, (Address) NIL, &newNameInfoPtr);
- if (status == FS_LOOKUP_REDIRECT) {
- Rpc_ReplyMem *replyMemPtr;
-
- storagePtr->replyDataPtr = (Address) newNameInfoPtr;
- storagePtr->replyDataSize = sizeof(Fs_RedirectInfo);
- storagePtr->replyParamPtr = (Address) malloc(sizeof (int));
- storagePtr->replyParamSize = sizeof (int);
- *((int *) (storagePtr->replyParamPtr)) = newNameInfoPtr->prefixLength;
-
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, status, storagePtr, Rpc_FreeMem,
- (ClientData)replyMemPtr);
- } else {
- Rpc_Reply(srvToken, status, storagePtr, (int (*)())NIL,
- (ClientData)NIL);
- }
-
- return(SUCCESS);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtMakeDir --
- *
- * Make the named directory. This uses the RPC_FS_MAKE_DIR call
- * to invoke FslclMakeDir on the file server.
- *
- * Results:
- * A return code from the file server or the RPC.
- *
- * Side effects:
- * Makes the directory.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- FsrmtMakeDir(prefixHandle, relativeName, argsPtr, resultsPtr,
- newNameInfoPtrPtr)
- Fs_HandleHeader *prefixHandle; /* Handle from the prefix table */
- char *relativeName; /* The name of the directory to create */
- Address argsPtr; /* Ref. to Fs_OpenArgs */
- Address resultsPtr; /* == NIL */
- Fs_RedirectInfo **newNameInfoPtrPtr;/* We return this if the server leaves
- * its domain during the lookup. */
- {
- ReturnStatus status;
- Rpc_Storage storage;
- Fs_RedirectInfo redirectInfo;
- int prefixLength;
-
- storage.requestParamPtr = (Address) argsPtr;
- storage.requestParamSize = sizeof(Fs_OpenArgs);
- storage.requestDataPtr = (Address) relativeName;
- storage.requestDataSize = strlen(relativeName) + 1;
- storage.replyParamPtr = (Address) &prefixLength;
- storage.replyParamSize = sizeof (int);
- storage.replyDataPtr = (Address)&redirectInfo;
- storage.replyDataSize = sizeof(Fs_RedirectInfo);
-
- status = Rpc_Call(prefixHandle->fileID.serverID, RPC_FS_MKDIR, &storage);
- if (status == FS_LOOKUP_REDIRECT) {
- *newNameInfoPtrPtr = mnew(Fs_RedirectInfo);
- (*newNameInfoPtrPtr)->prefixLength = prefixLength;
- (void)strcpy((*newNameInfoPtrPtr)->fileName, redirectInfo.fileName);
- }
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcMakeDir --
- *
- * Handle a make directory request from a client.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then an error is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcMakeDir(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* Command identifier */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- ReturnStatus status;
- Fs_HandleHeader *prefixHandlePtr;
- Fs_RedirectInfo *newNameInfoPtr;
- Fs_OpenArgs *openArgsPtr;
- int domainType;
-
- openArgsPtr = (Fs_OpenArgs *) storagePtr->requestParamPtr;
- if (openArgsPtr->prefixID.serverID != rpc_SpriteID) {
- return(GEN_INVALID_ARG);
- }
-
- prefixHandlePtr =
- (*fsio_StreamOpTable[openArgsPtr->prefixID.type].clientVerify)
- (&openArgsPtr->prefixID, clientID, &domainType);
- if (prefixHandlePtr == (Fs_HandleHeader *) NIL) {
- return(FS_STALE_HANDLE);
- }
- Fsutil_HandleRelease(prefixHandlePtr, TRUE);
-
- fs_Stats.srvName.makeDirs++;
- newNameInfoPtr = (Fs_RedirectInfo *) NIL;
- status = (*fs_DomainLookup[domainType][FS_DOMAIN_MAKE_DIR])(prefixHandlePtr,
- (char *)storagePtr->requestDataPtr,
- (Address) openArgsPtr, (Address) NIL, &newNameInfoPtr);
- if (status == FS_LOOKUP_REDIRECT) {
- Rpc_ReplyMem *replyMemPtr;
-
- storagePtr->replyDataPtr = (Address)newNameInfoPtr;
- storagePtr->replyDataSize = sizeof(Fs_RedirectInfo);
- storagePtr->replyParamPtr = (Address) malloc(sizeof (int));
- storagePtr->replyParamSize = sizeof (int);
- *((int *)(storagePtr->replyParamPtr)) = newNameInfoPtr->prefixLength;
-
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, status, storagePtr, Rpc_FreeMem,
- (ClientData)replyMemPtr);
- } else {
- Rpc_Reply(srvToken, status, storagePtr, (int (*)())NIL,
- (ClientData)NIL);
- }
-
- return(SUCCESS);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtMakeDevice --
- *
- * Create a device file. This uses the RPC_FS_MAKE_DEV call to create
- * the special file on the file server.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Makes a device file.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- FsrmtMakeDevice(prefixHandle, relativeName, argsPtr, resultsPtr,
- newNameInfoPtrPtr)
- Fs_HandleHeader *prefixHandle; /* Handle from the prefix table */
- char *relativeName; /* The name of the file. */
- Address argsPtr; /* Ref. to FsMakeDevArgs */
- Address resultsPtr; /* == NIL */
- Fs_RedirectInfo **newNameInfoPtrPtr;/* We return this if the server leaves
- * its domain during the lookup. */
- {
- ReturnStatus status;
- Rpc_Storage storage;
- Fs_RedirectInfo redirectInfo;
- int prefixLength;
-
- storage.requestParamPtr = (Address) argsPtr;
- storage.requestParamSize = sizeof(Fs_MakeDeviceArgs);
- storage.requestDataPtr = (Address) relativeName;
- storage.requestDataSize = strlen(relativeName) + 1;
- storage.replyParamPtr = (Address) &prefixLength;
- storage.replyParamSize = sizeof (int);
- storage.replyDataPtr = (Address)&redirectInfo;
- storage.replyDataSize = sizeof(Fs_RedirectInfo);
-
- status = Rpc_Call(prefixHandle->fileID.serverID, RPC_FS_MKDEV, &storage);
- if (status == FS_LOOKUP_REDIRECT) {
- *newNameInfoPtrPtr = mnew(Fs_RedirectInfo);
- (*newNameInfoPtrPtr)->prefixLength = prefixLength;
- (void)strcpy((*newNameInfoPtrPtr)->fileName, redirectInfo.fileName);
- }
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_RpcMakeDev --
- *
- * Service stub for RPC_FS_MKDEV. This calls FslclMakeDevice.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then an error is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /*ARGSUSED*/
- ReturnStatus
- Fsrmt_RpcMakeDev(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* Command identifier */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- ReturnStatus status;
- Fs_MakeDeviceArgs *makeDevArgsPtr;
- Fs_HandleHeader *prefixHandlePtr;
- Fs_RedirectInfo *newNameInfoPtr;
- int domainType;
-
- makeDevArgsPtr = (Fs_MakeDeviceArgs *) storagePtr->requestParamPtr;
- prefixHandlePtr =
- (*fsio_StreamOpTable[makeDevArgsPtr->open.prefixID.type].clientVerify)
- (&makeDevArgsPtr->open.prefixID, clientID, &domainType);
- if (prefixHandlePtr == (Fs_HandleHeader *) NIL) {
- return(FS_STALE_HANDLE);
- }
- Fsutil_HandleRelease(prefixHandlePtr, TRUE);
-
- fs_Stats.srvName.makeDevices++;
- newNameInfoPtr = (Fs_RedirectInfo *) NIL;
- status = (*fs_DomainLookup[domainType][FS_DOMAIN_MAKE_DEVICE])(prefixHandlePtr,
- (char *)storagePtr->requestDataPtr, (Address) makeDevArgsPtr,
- (Address) NIL, &newNameInfoPtr);
- if (status == FS_LOOKUP_REDIRECT) {
- Rpc_ReplyMem *replyMemPtr;
-
- storagePtr->replyDataPtr = (Address)newNameInfoPtr;
- storagePtr->replyDataSize = sizeof(Fs_RedirectInfo);
- storagePtr->replyParamPtr = (Address) malloc(sizeof (int));
- storagePtr->replyParamSize = sizeof (int);
- *((int *) (storagePtr->replyParamPtr)) = newNameInfoPtr->prefixLength;
-
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, status, storagePtr, Rpc_FreeMem,
- (ClientData)replyMemPtr);
- } else {
- Rpc_Reply(srvToken, status, storagePtr, (int (*)())NIL,
- (ClientData)NIL);
- }
- return(SUCCESS);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TwoNameOperation --
- *
- * Common stub for renaming a file or making a hard link.
- *
- * Results:
- * A return status.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- static ReturnStatus
- TwoNameOperation(command, prefixHandle1, relativeName1, prefixHandle2,
- relativeName2, lookupArgsPtr, newNameInfoPtrPtr, name1ErrorPtr)
- int command; /* Which Rpc: Mv or Ln */
- Fs_HandleHeader *prefixHandle1; /* Handle from prefix table */
- char *relativeName1; /* The new name of the file. */
- Fs_HandleHeader *prefixHandle2; /* Handle from prefix table */
- char *relativeName2; /* The new name of the file. */
- Fs_LookupArgs *lookupArgsPtr; /* Contains IDs */
- Fs_RedirectInfo **newNameInfoPtrPtr; /* We return this if the server
- * leaves its domain during the
- * lookup. */
- Boolean *name1ErrorPtr; /* If we return REDIRECT or
- * STALE_HANDLE this indicates
- * if that applies to the first
- * pathname or the second */
- {
- Fs_2PathParams params;
- Fs_2PathData *requestDataPtr; /* too big for stack */
- Fs_2PathReply replyParams;
- Rpc_Storage storage;
- ReturnStatus status;
- Fs_RedirectInfo redirectInfo;
-
- requestDataPtr = mnew(Fs_2PathData);
-
- params.lookup = *lookupArgsPtr;
- params.lookup.prefixID = prefixHandle1->fileID;
- params.prefixID2 = prefixHandle2->fileID;
-
- (void)strcpy(requestDataPtr->path1, relativeName1);
- (void)strcpy(requestDataPtr->path2, relativeName2);
-
- storage.requestParamPtr = (Address) ¶ms;
- storage.requestParamSize = sizeof (Fs_2PathParams);
- storage.requestDataPtr = (Address) requestDataPtr;
- storage.requestDataSize = sizeof (Fs_2PathData);
-
- storage.replyParamPtr = (Address) &replyParams;
- storage.replyParamSize = sizeof (Fs_2PathReply);
- storage.replyDataPtr = (Address)&redirectInfo;
- storage.replyDataSize = sizeof(Fs_RedirectInfo);
-
- status = Rpc_Call(prefixHandle1->fileID.serverID, command, &storage);
- *name1ErrorPtr = replyParams.name1ErrorP;
- if (status == FS_LOOKUP_REDIRECT) {
- *newNameInfoPtrPtr = mnew(Fs_RedirectInfo);
- (*newNameInfoPtrPtr)->prefixLength = replyParams.prefixLength;
- (void)strcpy((*newNameInfoPtrPtr)->fileName, redirectInfo.fileName);
- }
- free((Address)requestDataPtr);
-
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Fsrmt_Rpc2Path --
- *
- * Common service stub for FsrmtRename and FsrmtHardLink.
- *
- * Results:
- * If this procedure returns SUCCESS then a reply has been sent to
- * the client. If the arguments are bad then FS_STALE_HANDLE is
- * returned and the main level sends back an error reply.
- *
- * Side effects:
- * Calls the local rename or hard link routine to attempt the lock
- * operation.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- Fsrmt_Rpc2Path(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* Command identifier */
- Rpc_Storage *storagePtr; /* The request fields refer to the request
- * buffers and also indicate the exact amount
- * of data in the request buffers. The reply
- * fields are initialized to NIL for the
- * pointers and 0 for the lengths. This can
- * be passed to Rpc_Reply */
- {
- register Fs_2PathParams *paramsPtr;
- register Fs_LookupArgs *lookupArgsPtr;
- register Fs_HandleHeader *prefixHandle1Ptr;
- register Fs_HandleHeader *prefixHandle2Ptr;
- register Rpc_ReplyMem *replyMemPtr;
- Fs_RedirectInfo *newNameInfoPtr;
- Boolean name1Error = FALSE;
- Fs_2PathReply *replyParamsPtr;
- Fs_2PathData *pathDataPtr;
- ReturnStatus status = SUCCESS;
- int domainType;
-
- if (storagePtr->requestParamSize < sizeof(Fs_2PathParams)) {
- printf("Fsrmt_Rpc2Path: rpc from host %d had undersize param (%d)\n",
- clientID, storagePtr->requestParamSize);
- status = GEN_INVALID_ARG;
- goto exit;
- }
- if (storagePtr->requestDataSize < sizeof(Fs_2PathData)) {
- printf("Fsrmt_Rpc2Path: rpc from host %d had undersize data (%d)\n",
- clientID, storagePtr->requestDataSize);
- status = GEN_INVALID_ARG;
- goto exit;
- }
- paramsPtr = (Fs_2PathParams *)storagePtr->requestParamPtr;
- pathDataPtr = (Fs_2PathData *)storagePtr->requestDataPtr;
- lookupArgsPtr = ¶msPtr->lookup;
- prefixHandle1Ptr =
- (*fsio_StreamOpTable[lookupArgsPtr->prefixID.type].clientVerify)
- (&lookupArgsPtr->prefixID, clientID, &domainType);
-
- if (prefixHandle1Ptr == (Fs_HandleHeader *)NIL) {
- name1Error = TRUE;
- status = FS_STALE_HANDLE;
- goto exit;
- } else {
- Fsutil_HandleUnlock(prefixHandle1Ptr);
- }
- if (paramsPtr->prefixID2.serverID != rpc_SpriteID) {
- /*
- * Second pathname doesn't even start with us. However, we are
- * called in case the first pathname redirects away from us.
- */
- prefixHandle2Ptr = (Fs_HandleHeader *)NIL;
- } else {
- prefixHandle2Ptr =
- (*fsio_StreamOpTable[paramsPtr->prefixID2.type].clientVerify)
- (¶msPtr->prefixID2, clientID, (int *)NIL);
- if (prefixHandle2Ptr == (Fs_HandleHeader *)NIL) {
- Fsutil_HandleRelease(prefixHandle1Ptr, FALSE);
- name1Error = FALSE;
- status = FS_STALE_HANDLE;
- goto exit;
- } else {
- Fsutil_HandleUnlock(prefixHandle2Ptr);
- }
- }
-
- newNameInfoPtr = (Fs_RedirectInfo *) NIL;
- if (command == RPC_FS_RENAME) {
- fs_Stats.srvName.renames++;
- command = FS_DOMAIN_RENAME;
- } else if (command == RPC_FS_LINK) {
- fs_Stats.srvName.hardLinks++;
- command = FS_DOMAIN_HARD_LINK;
- } else {
- printf( "Fsrmt_Rpc2Path: Bad command %d\n", command);
- status = FS_INVALID_ARG;
- }
- if (status == SUCCESS) {
- status = (*fs_DomainLookup[domainType][command])(prefixHandle1Ptr,
- pathDataPtr->path1, prefixHandle2Ptr, pathDataPtr->path2,
- lookupArgsPtr, &newNameInfoPtr, &name1Error);
- }
- Fsutil_HandleRelease(prefixHandle1Ptr, FALSE);
- if (prefixHandle2Ptr != (Fs_HandleHeader *)NIL) {
- Fsutil_HandleRelease(prefixHandle2Ptr, FALSE);
- }
- exit:
- replyParamsPtr = (Fs_2PathReply *) malloc(sizeof (Fs_2PathReply));
- replyParamsPtr->name1ErrorP = name1Error;
- storagePtr->replyParamPtr = (Address) replyParamsPtr;
- storagePtr->replyParamSize = sizeof (Fs_2PathReply);
- if (status == FS_LOOKUP_REDIRECT) {
- replyParamsPtr->prefixLength = newNameInfoPtr->prefixLength;
- storagePtr->replyDataPtr = (Address) newNameInfoPtr;
- storagePtr->replyDataSize = sizeof(int) +
- strlen(newNameInfoPtr->fileName) + 1;
- } else {
- replyParamsPtr->prefixLength = 0;
- /*
- * Reply data ptr already set to NIL
- */
- }
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = (Address) replyParamsPtr;
- replyMemPtr->dataPtr = (Address) storagePtr->replyDataPtr;
- Rpc_Reply(srvToken, status, storagePtr,
- (int (*)()) Rpc_FreeMem, (ClientData) replyMemPtr);
-
- return(SUCCESS);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtRename --
- *
- * Stub for renaming a file.
- *
- * Results:
- * A return status.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- FsrmtRename(prefixHandle1, relativeName1, prefixHandle2, relativeName2,
- lookupArgsPtr, newNameInfoPtrPtr, name1ErrorPtr)
- Fs_HandleHeader *prefixHandle1; /* Handle from the prefix table */
- char *relativeName1; /* The new name of the file. */
- Fs_HandleHeader *prefixHandle2; /* Token from the prefix table */
- char *relativeName2; /* The new name of the file. */
- Fs_LookupArgs *lookupArgsPtr; /* Contains IDs */
- Fs_RedirectInfo **newNameInfoPtrPtr; /* We return this if the server leaves
- * its domain during the lookup. */
- Boolean *name1ErrorPtr; /* TRUE if redirect info or other error
- * condition if for the first pathname,
- * FALSE means error is on second pathname. */
- {
- return(TwoNameOperation(RPC_FS_RENAME, prefixHandle1, relativeName1,
- prefixHandle2, relativeName2, lookupArgsPtr,
- newNameInfoPtrPtr, name1ErrorPtr));
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * FsrmtHardLink --
- *
- * Stub for making a hard link between two files.
- *
- * Results:
- * A return status.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- FsrmtHardLink(prefixHandle1, relativeName1, prefixHandle2, relativeName2,
- lookupArgsPtr, newNameInfoPtrPtr, name1ErrorPtr)
- Fs_HandleHeader *prefixHandle1; /* Token from the prefix table */
- char *relativeName1; /* The new name of the file. */
- Fs_HandleHeader *prefixHandle2; /* Token from the prefix table */
- char *relativeName2; /* The new name of the file. */
- Fs_LookupArgs *lookupArgsPtr; /* Contains IDs */
- Fs_RedirectInfo **newNameInfoPtrPtr; /* We return this if the server
- * leaves its domain during the lookup*/
- Boolean *name1ErrorPtr; /* TRUE if redirect info or other error is
- * for first path, FALSE if for the second. */
- {
- return(TwoNameOperation(RPC_FS_LINK, prefixHandle1, relativeName1,
- prefixHandle2, relativeName2, lookupArgsPtr,
- newNameInfoPtrPtr, name1ErrorPtr));
- }
-